﻿using System;
using System.Collections.Generic;
using System.Text;

namespace NielsRask.K242.Core
{
	class Governor2 : IGovernor
    {
   		private Colony colony;
		private AI.Emperor emperor;

        public Governor2(Colony colony, AI.Emperor emperor)
		{
			this.colony = colony;
			this.BuildingQueue = new Queue<BuildingType>();
			this.ShipQueue = new Queue<Ship>();
			this.emperor = emperor;
		}

        Building[] buildings = {new Buildings.Energy(1),
                               new Buildings.Food(),
                               new Buildings.Water(),
                               new Buildings.Housing(1)};
		//public ColonyLevel TargetLevel { get; set; }

		public Queue<BuildingType> BuildingQueue { get; private set; }

		public Queue<Ship> ShipQueue { get; private set; }

        public void Update()
        {

			if (colony.Level == ColonyLevel.NavalBase && ShipQueue.Count > 0)
			{
				Ship ship = ShipQueue.Peek();
				ship.Build(20);
				if (ship.IsCompleted)
				{
					Console.WriteLine("A " + ship.GetType().Name + " was completed and has entered service");
					colony.HomeFleet.Add( ShipQueue.Dequeue() );
				}
			}
			// hvis der er mere end  ... 3? bygninger der ikke er færdige endnu, så return;
			if (BuildingQueue.Count > 0)
			{
				colony.Build(BuildingQueue.Dequeue());
				return;
			}
            //find behovene

            // afsøg hvilke bygninger der bedst kan afhjælpe behov
			int powerNeed = colony.Power.ProjectedUsed - colony.Power.ProjectedAvailable;
			//int powerNeed = colony.Power.Used - colony.Power.Available;
			//if (powerNeed < 0) powerNeed = 0;

			int housingNeed = colony.Population.ProjectedUsed - colony.Population.ProjectedAvailable;
			//int housingNeed = colony.Population.Used - colony.Population.Available;
			//if (housingNeed < 0) housingNeed = 0;

			int waterNeed = colony.Water.ProjectedUsed - colony.Water.ProjectedAvailable;
			//int waterNeed = colony.Water.Used - colony.Water.Available;
			//if (waterNeed < 0) waterNeed = 0;

			int foodNeed = colony.Food.ProjectedUsed - colony.Food.ProjectedAvailable;
			//int foodNeed = colony.Food.Used - colony.Food.Available;
			//if (foodNeed < 0) foodNeed = 0;

			//int discontent = (int)Math.Pow(powerNeed + housingNeed + waterNeed + foodNeed, 2);
			int discontent = (powerNeed * powerNeed) * (powerNeed < 0 ? -1 : 1)
				+ (housingNeed * housingNeed) * (housingNeed < 0 ? -1 : 1)
				+ (waterNeed * waterNeed) * (waterNeed < 0 ? -1 : 1)
				+ (foodNeed * foodNeed) * (foodNeed < 0 ? -1 : 1);

			if (discontent <= 0)
				return;

			//Console.WriteLine("discontent: " + discontent + " (" + powerNeed + ", " + housingNeed + ", " + waterNeed + ", " + foodNeed + ")");

            Building best = buildings[0];
            int bestDiscontent = GetResultingDiscontent(best, powerNeed, housingNeed, waterNeed, foodNeed, colony.Population.Available);
			//Console.WriteLine("[0] "+best.Type+" gives discontent = "+bestDiscontent);
            for (int i = 1; i < buildings.Length; i++ )
            {
				int buildingDiscontent = GetResultingDiscontent(buildings[i], powerNeed, housingNeed, waterNeed, foodNeed, colony.Population.Available);
				if (buildingDiscontent < bestDiscontent)
				{
					bestDiscontent = buildingDiscontent;
					best = buildings[i];
				}
				//Console.WriteLine("[" + i + "] " + buildings[i].Type + " gives discontent = " + buildingDiscontent);
            }
			//Console.WriteLine("discontent is best counteracted by building " + best.Type);

			colony.Build(best.Type);	// eller skal den i køen?
        }
		private int GetResultingDiscontent(Building b, int powerNeed, int housingNeed, int waterNeed, int foodNeed, int population) 
		{
			//powerNeed -= ( b.PowerGenerated - b.PowerUsed );
			//if ( powerNeed < 0 ) powerNeed = 0;
			//housingNeed -= ( b.LivingSpace - population );	// powerused skal være population ..
			//if ( housingNeed < 0 ) housingNeed = 0;
			//waterNeed -= ( b.WaterProduced - population );	// powerused skal være population
			//if ( waterNeed < 0 ) waterNeed = 0;
			//foodNeed -= ( b.FoodProduced - population );		// powerused skal være population
			//if ( foodNeed < 0 ) foodNeed = 0;

			// alternativ
			powerNeed -= ( b.PowerGenerated - b.PowerUsed );
			if ( powerNeed < 0 ) powerNeed = 0;

			housingNeed -= b.LivingSpace;	// powerused skal være population ..
			if ( housingNeed < 0 ) housingNeed = 0;

			waterNeed -= b.WaterProduced;	// powerused skal være population
			if ( waterNeed < 0 ) waterNeed = 0;

			foodNeed -= b.FoodProduced;		// powerused skal være population
			if ( foodNeed < 0 ) foodNeed = 0;


	//		int discontent = (powerNeed * powerNeed) + (housingNeed * housingNeed) + (waterNeed * waterNeed) + (foodNeed * foodNeed);
		//	int discontent = (int)Math.Pow(powerNeed + housingNeed + waterNeed + foodNeed, 2);

			int discontent = (int)(0.1 * powerNeed * powerNeed) * (powerNeed < 0 ? -1 : 1)
							+ (housingNeed * housingNeed) * (housingNeed < 0 ? -1 : 1)
							+ (waterNeed * waterNeed) * (waterNeed < 0 ? -1 : 1)
							+ (foodNeed * foodNeed) * (foodNeed < 0 ? -1 : 1);
							//+ (b.Cost * b.Cost) ;

			return discontent;
		}
    }
}
